#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <unordered_set>
#include <string>
#include <algorithm>  // 添加该头文件用于打乱
#include "easyrdlist.h"
using namespace std;

// 定义变量
bool f = false;  //为第24行定义旗帜
int n, m;
char t;
vector<int> r; // 存储权重抽取的人员索引
unordered_set<int> drawn; // 用于记录已经抽中的人员
struct rdlist {
    string name; // 使用 string 存储名字
    int num{ };
    int right{ }; // 权重
} a[100001];

// 抽取函数，避免重复
void rd() {
    if (drawn.size() == r.size()) {
        cout << "!> 所有人员都已经抽取过或权重均为0，无法继续抽取！" << endl;
        f = true;  //升旗
        return;
    }

    while (true) {
        int rdresult = rand() % r.size(); // 随机抽取
        if (drawn.find(r[rdresult]) == drawn.end()) { // 检查是否已经抽中
            drawn.insert(r[rdresult]); // 标记为已抽中
            cout << "·> " << a[r[rdresult]].name << endl;
            return;
        }
    }
}

int main() {
    titlere(); //自定义头文件修改窗口标题
    // 标题输出
    cout << "--- 权重式随机抽取工具 1.1 ---" << endl;

    srand(time(NULL));  // 初始化随机数生成器

    cout << "!> 请输入抽取人数: ";
    cin >> n;

    cout << "!> 下面是数据的读入，按照 名字 权 的顺序读入" << endl;
    cout << "> 例如：张三 3" << endl;
    cout << "!> 权的等级为0-5级" << endl;

    // 读取参与抽取的人物数据
    for (int i = 1; i <= n; i++) {
        cin >> a[i].name;
        a[i].num = i; // 记录人员编号
        cin >> a[i].right; // 读取权重等级
        if (a[i].right > 5 || a[i].right < 0) {
            cout << "!> 等级超出范围，终止运行......" << endl;
            cout << "!> 输入任意字符退出......" << endl;
            cin >> t;
            return 0;
        }

        // 根据权重将人员的编号加入抽取池
        for (int j = 0; j < a[i].right; j++) {
            if (a[i].right > 0) {
                r.push_back(i); // 权重为 1 -> 1 次，2 -> 2 次，3 -> 3 次, 4 -> 4 次，5 -> 5 次
            }
        }
    }

    // 打乱抽取池的顺序
    random_shuffle(r.begin(), r.end());

    cout << endl;
    cout << "!> 请输入需要抽取的人数：";
    cin >> m;
    cout << endl;
    if (n < m) {
        cout << "!> 人数超出限制" << endl;;
        cout << "!> 输入任意字符退出......" << endl;
        cin >> t;
        return 0;
    }
    cout << "------------ 抽取名单 ------------" << endl;

    // 循环进行抽取
    for (int i = 1; i <= m; i++) {
        rd(); // 调用抽取函数
        if (f == true) {  //判断旗帜状态
            cout << "-----------------------------------" << endl;
            cout << "!> 抽取已结束，输入任意字符退出......" << endl;
            cin >> t;
            return 0;
        }
    }

    if (drawn.size() < m) {
        cout << "!> 没有足够的人被抽取，可能是所有人都已抽取过。" << endl;
        cout << "-----------------------------------" << endl;
        cout << "!> 抽取已结束，输入任意字符退出......" << endl;
        cin >> t;
        return 0;
    }

    cout << "-----------------------------------" << endl;
    cout << "!> 抽取已结束，输入任意字符退出......" << endl;
    cin >> t;

    return 0;
}
